home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Developer / StopWatch / Source / ClientInspector.m < prev    next >
Encoding:
Text File  |  1994-02-06  |  8.4 KB  |  419 lines

  1. /*
  2.  * For legal stuff see the file COPYRIGHT
  3.  */
  4. #import "ClientInfo.h"
  5. #import "ClientInspector.h"
  6. #import "SessionEditor.h"
  7. #import "ExpenseEditor.h"
  8. #import "Controller.h"
  9.  
  10. @interface ClientInspector(PRIVATE)
  11. - enableAdd:(BOOL)addFlag delete:(BOOL)delFlag modify:(BOOL)modFlag;
  12. - (void)enableAdd:(BOOL)flag;
  13. - (void)enableModify:(BOOL)flag;
  14. - (void)enableDelete:(BOOL)flag;
  15. - (void)enableUndelete:(BOOL)flag;
  16. - showView:newView mgr:(ViewMgr *)mgr;
  17. - (void)updateButtons;
  18. @end
  19.  
  20. @implementation ClientInspector
  21.  
  22. /*
  23.  * Allow only one ClientInspector object to be created.
  24.  */
  25. + sharedInstance
  26. {
  27.   static id obj;
  28.  
  29.   if ( ! obj ) {
  30.     obj = [[ClientInspector alloc] init];
  31.     [NXApp loadNibSection:"ClientInspector.nib" owner:obj withNames:NO];
  32.   }
  33.  
  34.   return obj;
  35. }
  36.  
  37. + (void)updateButtons
  38. {
  39.   [[self sharedInstance] updateButtons];
  40. }
  41.  
  42. - awakeFromNib
  43. {
  44.   NXRect frameRect;
  45.  
  46.   if (![popUpList isKindOf:[PopUpList class]])
  47.     popUpList = [popUpButton target];
  48.  
  49.   [currentView getFrame:&frameRect];
  50.  
  51.   [[sessionView removeFromSuperview] setFrame:&frameRect];
  52.   [[expenseView removeFromSuperview] setFrame:&frameRect];
  53.   [[clientView  removeFromSuperview] setFrame:&frameRect];
  54.  
  55.   [[panel contentView] replaceSubview:currentView with:sessionView];
  56.   currentView = sessionView;
  57.  
  58.   [viewsPanel free];
  59.   [panel setFrameAutosaveName:"ClientInspector"];
  60.   [self windowDidResize:panel];    /* make swap views adjust to saved size */
  61.  
  62.   [browser setDoubleAction:@selector(browserDoubleClick:)];
  63.   controller = [NXApp delegate];
  64.  
  65.   [self decacheBrowser];    /* requires 'controller' to be set first... */
  66.   [[browser matrixInColumn:0] selectCellAt:0 :0];
  67.   return self;
  68. }
  69.  
  70. - (void)decacheBrowser
  71. {
  72.   ClientInfo *info = [self selectedClient];    /* remember the selection */
  73.   [[controller clientList] sort];         /* in case the name was modified */
  74.   [browser loadColumnZero];            /* redisplay */
  75.   [self selectClient:info];             /* reinstate the selection */
  76. }
  77.  
  78. /*
  79.  * Redraw the current view, but don't expose the window
  80.  */
  81. - (void)decacheView
  82. {
  83.   List *clientList = [controller clientList];
  84.  
  85.   /*
  86.    * If there are no clients, force the display the Client View,
  87.    * since it's the only meaningful one.
  88.    */
  89.   if ( [clientList count] == 0 )
  90.     [self showClient:nil];
  91.  
  92.   [currentMgr mgrShow:self];
  93.   [self updateButtons];
  94. }
  95.  
  96. /*
  97.  * Called by Controller
  98.  */
  99. - display
  100. {
  101.   [self decacheView];
  102.   [panel makeKeyAndOrderFront:nil]; /* was just "orderFront:" */
  103.   return self;
  104. }
  105.  
  106. - (void)selectClientAt:(int)row
  107. {
  108.   Matrix *matrix = [browser matrixInColumn:0];
  109.   [matrix selectCellAt:row :0]; 
  110. }
  111.  
  112. - selectClient:(ClientInfo *)info
  113. {
  114.   id matrix = [browser matrixInColumn:0];
  115.   List *clientList = [controller clientList];
  116.   int i = [clientList indexOf:info];
  117.  
  118.   [matrix selectCellAt:i :0];
  119.   return self;
  120. }
  121.  
  122. - addClient:(ClientInfo *)info
  123. {
  124.   List *clientList = [controller clientList];
  125.   
  126.   [clientList addObjectIfAbsent:info];
  127.   [self decacheBrowser];
  128.   [controller decacheBrowser];
  129.   [self selectClient:info];
  130.   return self;
  131. }
  132.  
  133. /*
  134.  * Generic delete button - invoke the delete method of the
  135.  * currently selected view. If the return value is non-nil,
  136.  * we save the modified data structure to disk.
  137.  */
  138. - delete:sender
  139. {
  140.   if ( [currentMgr mgrDelete:self] ) {
  141.     [controller saveClientInfo];
  142.     [self updateButtons];
  143.   }
  144.  
  145.   return self;
  146. }
  147.  
  148. - undelete:sender
  149. {
  150.   if ( [currentMgr mgrUndelete:self] ) {
  151.     [controller saveClientInfo];
  152.     [self updateButtons];
  153.   }    
  154.  
  155.   return self;
  156. }
  157.  
  158. - add:sender
  159. {
  160.   if ( [currentMgr mgrAdd:self] ) {
  161.     [controller saveClientInfo];
  162.     [self updateButtons];
  163.   }
  164.   return self;
  165. }
  166.  
  167. - modify:sender
  168. {
  169.   if ( [currentMgr mgrModify:self] ) {
  170.     [controller saveClientInfo];
  171.     [self updateButtons];
  172.   }
  173.   return self;
  174. }
  175.  
  176. - (void)performAdd
  177. {
  178.   [addButton performClick:self];
  179. }
  180.  
  181. - (void)performModify
  182. {
  183.   [modifyButton performClick:self];
  184. }
  185.  
  186. /*
  187.  * Called when the client is selected in the inspector's top browser
  188.  */
  189. - browserClick:sender
  190. {
  191.   [currentMgr mgrShow:self];
  192.   [self updateButtons];
  193.   return self;
  194. }
  195.  
  196. - browserDoubleClick:sender
  197. {
  198.   if ( [currentMgr mgrDoubleClick:self] ) {
  199.     [controller saveClientInfo];
  200.     [self updateButtons];
  201.   }
  202.  
  203.   return self;
  204. }
  205.  
  206. /*
  207.  * Called by the Client mgr when the delete button is pressed.
  208.  */
  209. - (ClientInfo *)deleteSelectedClient
  210. {
  211.   List *clientList = [controller clientList];
  212.   ClientInfo *info = [clientList removeObject:[self selectedClient]];
  213.   [self decacheBrowser];
  214.   [controller decacheBrowser];
  215.   return info;
  216. }
  217.  
  218. - (ClientInfo *)selectedClient
  219. {
  220.   id matrix = [browser matrixInColumn:0];
  221.   List *clientList = [controller clientList];
  222.   return [clientList objectAt:[matrix selectedRow]];
  223. }
  224.  
  225. /*
  226.  * Called when a new session has been added via the main control panel.
  227.  * This allows the browser to update if necessary.
  228.  */
  229. - updatedInfo:info
  230. {
  231.   if ( info == [self selectedClient] )
  232.     [currentMgr mgrShow:self];    /* force redisplay */
  233.  
  234.   return self;
  235. }
  236.  
  237. /*
  238.  * Delegated methods of NXBrowser
  239.  */
  240. - (int)browser:sender fillMatrix:matrix inColumn:(int)column
  241. {
  242.   List *clientList = [controller clientList];
  243.   int i, count = [clientList count];
  244.   const char *name;
  245.   id cell;
  246.   
  247.   for ( i = 0; i < count; i++ ) {
  248.     [matrix addRow];
  249.     name = [[clientList objectAt:i] clientName];
  250.     cell = [matrix cellAt:i :0];    /* 1 dimen. matrix: always use col 0! */
  251.     [cell setStringValue:name];
  252.     [cell setLoaded:YES];
  253.     [cell setLeaf:YES];
  254.   }
  255.  
  256.   return count ;
  257. }
  258.  
  259. - (void)closeMonth
  260. {
  261.   [sessionMgr forgetDeletions];
  262.   [expenseMgr forgetDeletions];
  263.   [clientMgr  forgetDeletions];
  264. }
  265.  
  266. /*
  267.  * Force button title to the right state. This is necessary
  268.  * because PopupLists are a kludge.
  269.  */
  270. - (void)chooseCell:cell
  271. {
  272.   [popUpButton setTitle:[cell title]];
  273.   [[popUpList itemList] selectCell:cell];
  274. }
  275.  
  276. - showClient:sender
  277. {
  278.   [self chooseCell:clientMenuCell];
  279.   [self showView:clientView mgr:clientMgr];
  280.   return self;
  281. }
  282.  
  283. - showHours:sender
  284. {
  285.   [self chooseCell:sessionMenuCell];
  286.   [self showView:sessionView mgr:sessionMgr];
  287.   return self;
  288. }
  289.  
  290. - showExpenses:sender
  291. {
  292.   [self chooseCell:expenseMenuCell];
  293.   [self showView:expenseView mgr:expenseMgr];
  294.   return self;
  295. }
  296.  
  297. - setDocEdited:(BOOL)flag
  298. {
  299.   [panel setDocEdited:flag];
  300.   return self;
  301. }
  302.  
  303. /*
  304.  * Delegated methods of Window
  305.  */
  306. - windowDidResize:sender
  307. {
  308.   NXRect frameRect;
  309.  
  310.   [currentView getFrame:&frameRect];
  311.  
  312.   /* Tell the other swap views their new size */
  313.   [sessionView setFrame:&frameRect];
  314.   [expenseView setFrame:&frameRect];
  315.   [clientView  setFrame:&frameRect];
  316.   return self;
  317. }
  318.  
  319. @end
  320.  
  321.  
  322. @implementation ClientInspector(PRIVATE)
  323.  
  324. - enableAdd:(BOOL)addFlag delete:(BOOL)delFlag modify:(BOOL)modFlag
  325. {
  326.   [controller enableAdd:addFlag];
  327.   [controller enableModify:modFlag];
  328.  
  329.   [self enableAdd:addFlag];
  330.   [self enableModify:modFlag];
  331.   [self enableDelete:delFlag];
  332.  
  333.   [self enableUndelete:[currentMgr canUndelete]];
  334.   return self;
  335. }
  336.  
  337. - showView:newView mgr:(ViewMgr *)mgr
  338. {
  339.   [panel disableFlushWindow];
  340.  
  341.   if (newView != currentView) {
  342.  
  343.     /* Bail out if the user want to save their edits */
  344.     if ( [currentMgr isEditing] == NO ||
  345.     NXRunAlertPanel( [NXApp appName],
  346.             "Modified data has not been saved",
  347.             "Let me save it!",
  348.             "I don't give a hoot", NULL ) != NX_ALERTDEFAULT ) {
  349.  
  350.       [[panel contentView] replaceSubview:currentView with:newView];
  351.  
  352.       currentView = newView;
  353.       currentMgr  = mgr;
  354.  
  355.       [mgr mgrShow:self];
  356.       [self setDocEdited:[mgr isEditing]];
  357.       [panel display];
  358.       [self updateButtons];
  359.     }
  360.   }
  361.  
  362.   [[panel reenableFlushWindow] flushWindow];
  363.   [panel makeKeyAndOrderFront:nil]; /* was just orderFront: before */
  364.   return self;
  365. }
  366.  
  367. /*
  368.  * These are packaged as methods so we can easily add accelerator
  369.  * keys that are controlled at the same time...
  370.  */
  371. - (void)enableAdd:(BOOL)flag
  372. {
  373.   [addButton setEnabled:flag];
  374. }
  375.  
  376. - (void)enableModify:(BOOL)flag
  377. {
  378.   [modifyButton setEnabled:flag];
  379. }
  380.  
  381. - (void)enableDelete:(BOOL)flag
  382. {
  383.   [controller enableDelete:flag];
  384.   [deleteButton setEnabled:flag]; 
  385. }
  386.  
  387. /*
  388.  * Control the menu item from here...
  389.  */
  390. - (void)enableUndelete:(BOOL)flag
  391. {
  392.   [controller enableUndelete:flag];
  393. }
  394.  
  395. - (void)updateButtons
  396. {
  397.   BOOL flag = ([[controller clientList] count] == 0 ? NO : YES);
  398.  
  399.   [self enableAdd:[currentMgr canAdd]
  400.      delete:[currentMgr canDelete]
  401.      modify:[currentMgr canModify]];
  402.  
  403.   /* Enable these when there are clients */
  404.   [sessionMenuCell setEnabled:flag];
  405.   [expenseMenuCell setEnabled:flag];
  406. }
  407.  
  408. /*
  409.  * First responder method - pass to view manager
  410.  */
  411. - selectAll:sender
  412. {
  413.   if ( [currentMgr respondsTo:@selector(selectAll:)] )
  414.     return [currentMgr selectAll:sender];
  415.  
  416.   return nil;            /* is this the right thing to do? */
  417. }
  418. @end
  419.